package service

import (
	"RocFamilySystem/internal/repository"
	"RocFamilySystem/models"
	"RocFamilySystem/pkg/generator"
	"RocFamilySystem/tools/container"
	"archive/zip"
	"bytes"
	"fmt"
	"github.com/gin-gonic/gin"
	"runtime/debug"
	"strings"
	"text/template"
)

type GeneratorTableService struct {
	GeneratorTableRepository *repository.GeneratorTableRepository
}

// 初始化
func init() {
	registerContainer["GeneratorTableService"] = &GeneratorTableService{}
}

// SetRepository 设置持久层
func (service *GeneratorTableService) SetRepository(generatorTableRepository *repository.GeneratorTableRepository) {
	service.GeneratorTableRepository = generatorTableRepository
}

// AddGeneratorTable 添加生成表
func (service *GeneratorTableService) AddGeneratorTable(generatorTable *models.GeneratorTable) {
	service.GeneratorTableRepository.InsertGeneratorTable(generatorTable)
}

// RemoveGeneratorTable 删除生成表
func (service *GeneratorTableService) RemoveGeneratorTable(generatorTableId int) {
	service.GeneratorTableRepository.DeleteGeneratorTable(generatorTableId)
}

// ModifyGeneratorTable 修改生成表
func (service *GeneratorTableService) ModifyGeneratorTable(generatorTable *models.GeneratorTable) {
	service.GeneratorTableRepository.UpdateGeneratorTable(generatorTable)
}

// QueryGeneratorTable 查询生成表
func (service *GeneratorTableService) QueryGeneratorTable(generatorTable *models.GeneratorTable, pageNum, pageSize int) PageInfo {
	tables, total := service.GeneratorTableRepository.SelectGeneratorTable(generatorTable, pageNum, pageSize)
	return toPageInfo(pageNum, pageSize, total, tables)
}

// QueryGeneratorTableById 通过ID查询生成表
func (service *GeneratorTableService) QueryGeneratorTableById(id int) models.GeneratorTable {
	return service.GeneratorTableRepository.SelectGeneratorTableById(id)
}

// GeneratorCodePreview 生成代码预览
func (service *GeneratorTableService) GeneratorCodePreview(tableId, templateId int) []gin.H {

	//表单内容
	table := service.QueryGeneratorTableById(tableId)
	generatorTemplateService, _ := container.GetBeanContainer("service.GeneratorTemplateService")
	//生成模板内容
	templateObj := generatorTemplateService.(*GeneratorTemplateService).QueryGeneratorTemplateById(templateId)

	files := make([]gin.H, len(templateObj.Files))
	var funcMap = template.FuncMap{
		"UpperToLine": generator.UpperToLine,
		"FirstLower":  generator.FastLower,
		"ToUpper":     strings.ToUpper,
		"Sub":         func(num1, num2 int) int { return num1 - num2 },
		"Add":         func(num1, num2 int) int { return num1 + num2 },
	}
	for index, val := range templateObj.Files {
		tmp, err := template.New(*val.FileName).Funcs(funcMap).Parse(*val.Content)
		if err != nil {
			debug.PrintStack()
		}
		parse := template.Must(tmp, err)
		var buf bytes.Buffer
		err = parse.Execute(&buf, table)
		handleServiceErr(err, "错误：生成模板语法错误，请检查！")
		files[index] = gin.H{
			"content":  buf.String(),
			"language": *val.Language,
			"fileName": fmt.Sprintf("%s%s", generator.UpperToLine(table.TabName), *val.FileName),
		}
	}

	return files
}

// GeneratorCodeDownload 下载代码
func (service *GeneratorTableService) GeneratorCodeDownload(tableId int, templateId int) bytes.Buffer {
	var buf bytes.Buffer
	zipFile := zip.NewWriter(&buf)
	files := service.GeneratorCodePreview(tableId, templateId)
	for _, file := range files {
		fileName := file["fileName"].(string)
		content := file["content"].(string)
		file, _ := zipFile.Create(fileName)
		_, _ = file.Write([]byte(content))
	}
	err := zipFile.Close()
	handleServiceErr(err, "下载模板失败！")
	return buf
}
